package com.motong.gongdan.controller.system;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.motong.gongdan.config.ResponseData;
import com.motong.gongdan.config.auth.UserLoginToken;
import com.motong.gongdan.entity.AssemblyWorkOrder;
import com.motong.gongdan.entity.AssemblyWorkOrderDetail;
import com.motong.gongdan.entity.PrintTemplate;
import com.motong.gongdan.service.*;
import com.motong.gongdan.util.LoginUtil;
import com.motong.gongdan.vo.system.AssemblyWorkOrder.query.AssemblyListQuery;
import com.motong.gongdan.vo.system.AssemblyWorkOrder.vo.AssemblyDetailProductVo;
import com.motong.gongdan.vo.system.AssemblyWorkOrder.vo.AssemblyEditVo;
import com.motong.gongdan.vo.system.AssemblyWorkOrder.vo.AssemblyListVo;
import com.motong.gongdan.vo.system.ExcelTemplate.vo.ExcelTemplateDataVo;
import com.motong.gongdan.vo.system.common.query.IdValueQuery;
import com.motong.gongdan.vo.system.printTemplate.vo.ExportDataByModelVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Api(tags = "装配工单")
@RestController
@RequestMapping("/sys/assembly")
public class AssemblyWorkOrderController {

    @Resource
    private AssemblyWorkOrderService assemblyWorkOrderService;

    @Resource
    private AssemblyWorkOrderDetailService assemblyWorkOrderDetailService;

    @Resource
    private CustomNumberService customNumberService;

    @Resource
    private PrintTemplateService printTemplateService;

    @Resource
    private UserService userService;

    @Resource
    private CommonService commonService;

    @ApiOperation("获取装配工单列表")
    @PostMapping("/getList")
    @UserLoginToken
    public ResponseData<List<AssemblyListVo>> getList(@RequestBody(required = false) AssemblyListQuery.QueryData query) {
        query = Optional.ofNullable(query).orElse(new AssemblyListQuery.QueryData());
        Page<AssemblyListVo> data = assemblyWorkOrderService.getList(new Page<>(query.getPage(), query.getLimit()), query);
        return ResponseData.success(data.getRecords(), data.getTotal());
    }

    @ApiOperation("获取装配工单详情")
    @PostMapping("/detail")
    @UserLoginToken
    public ResponseData<List<AssemblyDetailProductVo>> detail(@RequestBody IdValueQuery query) {
        if (!CollectionUtils.isEmpty(query.getLongIdList())) {
            List<AssemblyDetailProductVo> detailList = assemblyWorkOrderDetailService.getDetailByAssemblyId(query.getLongIdList().get(0), true);
            return ResponseData.success(detailList);
        }
        return ResponseData.success(Collections.emptyList());
    }


    @ApiOperation("编辑装配工单")
    @PostMapping("/edit")
    @UserLoginToken
    @Transactional(rollbackFor = Exception.class)
    public ResponseData<String> edit(@RequestBody AssemblyEditVo assemblyEditVo) {
        boolean isUpdate = Objects.nonNull(assemblyEditVo.getId());
        AssemblyWorkOrder assemblyWorkOrder = BeanUtil.toBean(assemblyEditVo, AssemblyWorkOrder.class);
        Integer loginUserId = LoginUtil.getLoginUserId();
        assemblyWorkOrder.setUpdateUser(loginUserId).setUpdateTime(new Date());
        int workerOrderIndex = 1;
        if (!StringUtils.hasLength(assemblyWorkOrder.getCode())) {
            String code = customNumberService.generator(11);
            if ("fail".equals(code)) {
                return ResponseData.fail(500, "流水号已用完，请手动输入");
            }
            assemblyWorkOrder.setCode(code);
        }
        if (assemblyWorkOrderService.count(new LambdaQueryWrapper<AssemblyWorkOrder>().eq(AssemblyWorkOrder::getCode, assemblyWorkOrder.getCode())
                .ne(isUpdate, AssemblyWorkOrder::getId, assemblyWorkOrder.getId())) > 0) {
            return ResponseData.fail(500, "装配工单编号已存在");
        }
        if (!isUpdate) {
            BigDecimal allPlanNum = assemblyEditVo.getDetailList().stream().map(AssemblyWorkOrderDetail::getWorkOrderPlanNum).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
            assemblyWorkOrder.setWorkOrderNum(assemblyEditVo.getDetailList().size()).setPlanedNum(allPlanNum).setFinishNum(BigDecimal.ZERO)
                    .setEndWorkerOrderNum(0).setCreateTime(new Date()).setCreateUser(loginUserId);
        } else {
            AssemblyWorkOrder oriAssemblyWorkOrder = assemblyWorkOrderService.getById(assemblyWorkOrder.getId());
            BigDecimal allPlanNum = assemblyEditVo.getDetailList().stream().map(AssemblyWorkOrderDetail::getWorkOrderPlanNum).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
            if (!allPlanNum.equals(oriAssemblyWorkOrder.getPlanedNum())){
                assemblyWorkOrder.setPlanedNum(allPlanNum);
            }
            if (!oriAssemblyWorkOrder.getWorkOrderNum().equals(assemblyEditVo.getDetailList().size())){
                assemblyWorkOrder.setWorkOrderNum(assemblyEditVo.getDetailList().size());
            }
            // 获取当前编号的位置
            AssemblyWorkOrderDetail lastOne = assemblyWorkOrderDetailService.getOne(new LambdaQueryWrapper<AssemblyWorkOrderDetail>()
                    .eq(AssemblyWorkOrderDetail::getAssemblyWorkOrderId, oriAssemblyWorkOrder.getId()).orderByDesc(AssemblyWorkOrderDetail::getId).last("LIMIT 1"));
            workerOrderIndex = Objects.isNull(lastOne) ? 1 : Integer.parseInt(lastOne.getWorkerOrderCode().substring(lastOne.getWorkerOrderCode().length() - 1)) + 1;
        }
        assemblyWorkOrder.setOther(JSONUtil.toJsonStr(Collections.EMPTY_LIST));
        if (!CollectionUtils.isEmpty(assemblyEditVo.getCustomFieldVos())) {
            String jsonStr = JSONUtil.toJsonStr(assemblyEditVo.getCustomFieldVos());
            assemblyWorkOrder.setOther(jsonStr);
            assemblyWorkOrder.setCustomFieldMess(JSONArray.parseArray(jsonStr));
        }
        assemblyWorkOrderService.saveOrUpdate(assemblyWorkOrder);
//        mongoTemplate.save(assemblyEditVo);

        assemblyEditVo.setId(assemblyWorkOrder.getId());
        //执行装配单内详情删除操作
        if (Objects.nonNull(assemblyEditVo.getDelDetailIds()) && !assemblyEditVo.getDelDetailIds().isEmpty()) {
            assemblyWorkOrderService.delDetail(assemblyEditVo.getDelDetailIds());
        }
        //保存或添加装配工单信息
        if (!CollectionUtils.isEmpty(assemblyEditVo.getDetailList())) {
            List<AssemblyWorkOrderDetail> detailList = assemblyEditVo.getDetailList();
            //分类详情的更新或添加
            Map<String, List<AssemblyWorkOrderDetail>> saveOrUpdateGroup = detailList.stream().collect(Collectors.groupingBy(i -> Objects.nonNull(i.getId()) ? "update" : "save"));
            // 执行内部详情保存操作
            assemblyWorkOrderService.saveDetail(saveOrUpdateGroup.get("save"), assemblyWorkOrder.getId(), assemblyWorkOrder.getCode(), workerOrderIndex);
            // 执行内部详情的更新操作
            assemblyWorkOrderService.updateDetail(saveOrUpdateGroup.get("update"));
        }

        return ResponseData.success(isUpdate ? "编辑成功!" : "添加成功!");
    }

    @ApiOperation("删除装配工单")
    @PostMapping("/del")
    @UserLoginToken
    public ResponseData<String> del(@RequestBody IdValueQuery query) {
        if (!CollectionUtils.isEmpty(query.getIdList())) {
            List<AssemblyWorkOrderDetail> list = assemblyWorkOrderDetailService.list(new LambdaQueryWrapper<AssemblyWorkOrderDetail>().in(AssemblyWorkOrderDetail::getAssemblyWorkOrderId, query.getIdList()));
            if (!CollectionUtils.isEmpty(list)) {
                assemblyWorkOrderService.delDetail(list.stream().map(AssemblyWorkOrderDetail::getId).collect(Collectors.toList()));
            }
            assemblyWorkOrderService.removeByIds(query.getIdList());
        }
        return ResponseData.success("删除成功!");
    }


    /**
     * 装配工单打印数据
     */
    @UserLoginToken
    @ApiOperation("装配工单打印数据导出")
    @PostMapping("/exportDataByModel")
    public void exportByTemplate(@RequestBody ExportDataByModelVo query, HttpServletResponse response) {
        // 获取模板信息
        PrintTemplate printTemplate = printTemplateService.getById(query.getId());
        List<ExcelTemplateDataVo> excelData = new ArrayList<>();
        if (Objects.isNull(printTemplate) || !StringUtils.hasLength(printTemplate.getTemplatePath())) {
            return;
        }
        // 获取数据
        query.getAssemblyIdList().forEach(assemblyId -> {
            //获取数据
            List<Map<String, Object>> listData;
            Map<String, Object> singleData;
            //装配工单
            singleData = assemblyWorkOrderService.getExportData(assemblyId);
            listData = assemblyWorkOrderService.getExportDataList(assemblyId);
            singleData.put("handleName", userService.getById(LoginUtil.getLoginUserId()).getName());
            singleData.put("handleTime", DateUtil.now());
            excelData.add(new ExcelTemplateDataVo().setSingleData(singleData).setListData(listData));
        });
        commonService.exportExcelData(response, printTemplate.getTemplatePath(), printTemplate.getTemplateName(), excelData);
    }

}
